<?php
/**
 * Created by PhpStorm.
 * User: 王峥宇
 * Date: 2019/3/19
 * Time: 15:21
 */

namespace app\api\controller;

use think\Controller;
use app\api\controller\Base;
use think\Loader;
use think\Request;
use think\Db;
header("Content-type:text/html;charset=utf-8");
Loader::import('Wxpay.Wxpay.WxPay', EXTEND_PATH, '.Api.php');//将附件放入根目录下的/extend
Loader::import('Wxpay.Wxpay.WxPay', EXTEND_PATH, '.Config.php');//将附件放入根目录下的/extend
Class Paywx extends Base
{
    //调用信息
    protected $config;
    public function _initialize()
    {
        $config=new \WxPayConfig();
        $this->config=$config->_config;
    }
    //支付
    public function pay(){
        $fee=input('price');//标价金额，交易金额
        $appid=$this->config['APPID'];//appid.
        $body='农厂汇-支付';
        $mch_id=$this->config['MCHID'];//商户号
        $nonce_str=$this->nonce_str();//随机字符串
        if(input('flg')==1) {
            $notify_url = $this->config['NOTIFY_URL']; //回调的url【自己填写】
        }elseif (input('flg')==2){
            $notify_url = $this->config['ZNOTIFY_URL']; //回调的url【自己填写】
        }
        $openid=$this->openid;//用户标识
        $out_trade_no=$this->order_number($openid);//商户订单号
        $spbill_create_ip=$this->get_client_ip();//服务器的ip【自己填写】;
        $total_fee=$fee*100;// 微信支付单位是分，所以这里需要*100$trade_type = 'JSAPI';//交易类型 默认
        $trade_type='JSAPI';//交易类型
        $data=array(
            'appid'=>$appid,//小程序id
            'body'=>$body,//商品描述
            'mch_id'=>$mch_id,//商家商户号
            'nonce_str'=>$nonce_str,//随机字符串
            'notify_url'=>$notify_url,//通知地址
            'openid'=>$openid,
            'out_trade_no'=>$out_trade_no,//商户订单号
            'spbill_create_ip'=>$spbill_create_ip,//终端ip
            'total_fee'=>$total_fee,//标价金额，交易金额
            'trade_type'=>$trade_type,
        );
        $sign=$this->sign($data);//签名
        $data['sign']=$sign;
        $xmldata=$this->xml($data);
        $url='https://api.mch.weixin.qq.com/pay/unifiedorder';//接口链接（微信小程序）
        $xml=$this->http_request($url,$xmldata);//调用支付接口
        $array = $this->getxml($xml);
        if($array['RETURN_CODE'] == 'SUCCESS' && $array['RESULT_CODE'] == 'SUCCESS') {
            $times=date('Y-m-d H:i:s');
            if(input('flg')==1) {
                db('pay')
                    ->where('uid', $this->uid)
                    ->insert(['number' => $out_trade_no, 'price' => $total_fee/100, 'uid' => $this->uid, 'createtime' => $times,'flg'=>'未付款']);
              
            }elseif (input('flg')==2){
                db('zpay')
                    ->where('uid',$this->uid)
                    ->insert(['number' => $out_trade_no, 'price' => $total_fee/100, 'uid' => $this->uid, 'zid'=>input('zid'), 'createtime' => $times,'flg'=>'未付款']);
            }
            $time = time();
            $tmp = '';//临时数组用于签名
            $tmp['appId'] = $appid;
            $tmp['nonceStr'] = $nonce_str;
            $tmp['package'] = 'prepay_id=' . $array['PREPAY_ID'];
            $tmp['signType'] = 'MD5';
            $tmp['timeStamp'] = "$time";

            $data['state'] = 200;
            $data['timeStamp'] = "$time";//时间戳
            $data['nonceStr'] = $nonce_str;//随机字符串
            $data['signType'] = 'MD5';//签名算法，暂支持 MD5
            $data['package'] = 'prepay_id=' . $array['PREPAY_ID'];//统一下单接口返回的 prepay_id 参数值，提交格式如：prepay_id=*
            $data['paySign'] = $this->sign($tmp);//签名,具体签名方案参见微信公众号支付帮助文档;
            $data['out_trade_no'] = $out_trade_no;
        }else{
            $data['state'] = 0;
            $data['text'] = "错误";
            $data['RETURN_CODE'] = $array['RETURN_CODE'];
            $data['RETURN_MSG'] = $array['RETURN_MSG'];
        }

        exit(json_encode($data));//exit;
    }
    //随机生成32位字符串
    private function nonce_str(){
        $result='';
        $str = 'QWERTYUIOPASDFGHJKLZXCVBNMqwertyuioplkjhgfdsamnbvcxz';
        for($i=0;$i<32;$i++){
            $result.=$str[rand(0,48)];
        }
        return $result;
    }

    //array->xml
    public function xml($data){
        ksort($data);
        $data_xml="<xml>";
        foreach ($data as $key=>$val){
            if(is_array($val)) {
            $data_xml .= "<" . $key ."><![CDATA[" . $val ."]]</" . $key . ">";
            }else{

            $data_xml.="<".$key.">".$val."</".$key .">";
            }
        }
        $data_xml.="</xml>";
        return $data_xml;
    }

    /*
    获取当前服务器的IP
    */
    public function get_client_ip(){
        if ($_SERVER['REMOTE_ADDR']) {
            $cip = $_SERVER['REMOTE_ADDR'];
        } elseif (getenv("REMOTE_ADDR")) {
            $cip = getenv("REMOTE_ADDR");
        } elseif (getenv("HTTP_CLIENT_IP")) {
            $cip = getenv("HTTP_CLIENT_IP");
        } else {
            $cip = "unknown";
        }
        return $cip;
    }
    /*
     * 订单号md5加密生成
     */
    private function order_number($openid){
        return md5($openid.time().rand(10,99));
    }
    //计算签名
    private function sign($data){
        $keys=$this->config['KEY'];
        //步骤一：按字典序排列参数
        ksort($data);
        $buff='';
        foreach ($data as $k=>$v) {
            if($k!="sign"&&$v!=""&&!is_array($v)){
                $buff.=$k."=".$v."&";
            }
        }
        $buff=trim($buff,"&");
        //步骤二：在string后面贾$key
        $string=$buff. "&key=".$keys;
        //步骤三：md5加密
        $string=md5($string);
        //步骤四：所有字符转化为大写
        $sign=strtoupper($string);
        //dump($sign);
        return $sign;
    }

    //创建CURL(校验)
    public function http_request($url,$data = null,$headers=array()){
        $curl = curl_init();
        if( count($headers) >= 1 ){
            curl_setopt($curl, CURLOPT_HTTPHEADER, $headers);
        }
        curl_setopt($curl, CURLOPT_URL, $url);
        curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, FALSE);
        curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, FALSE);
        if (!empty($data)){
            curl_setopt($curl, CURLOPT_POST, 1);
            curl_setopt($curl, CURLOPT_POSTFIELDS, $data);
        }
        curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
        $output = curl_exec($curl);
        curl_close($curl);
        return $output;
    }
    //获取xml
    private function getxml($xml){
        $p =xml_parser_create();
        xml_parse_into_struct($p, $xml, $vals, $index);
        xml_parser_free($p);
        $data=[];
        foreach ($index as $key=>$value) {
            if($key == 'xml' || $key == 'XML') continue;
            $tag=$vals[$value[0]]['tag'];
            $value=$vals[$value[0]]['value'];
            $data[$tag]=$value;
        }
        return $data;
    }
}